#pragma once

namespace Tmpl {

class Entity;
typedef std::deque<Entity*> GridEntArray;
typedef GridEntArray GridCell;

class Grid
{
public:
	enum CollisionType
	{
		COLLISION_WATER = -2,
		COLLISION_NONE	= -1,
	};

	static void Init(int size);
	static void Clear();

	static int GetSize();

	static void AddEntity(Entity* ent, int cellId);
	static void RemoveEntity(Entity* ent, int cellId);
	static void UpdateEntity(Entity* ent, int oldCellId, int newCellId);
	static const GridCell& GetEntitiesInCell(int x, int y);

	static Vec2f SolveOverlap(const Vec2f& pos, float size, Entity** entities, int maxEntities);

	static int GetCellIdFromXY(int x, int y);
	static int GetCellIdFromPos(const Vec2f& pos);
	GridCell& GetCellFromXY(int x, int y);
	static Vec2f GetCellCenter(int x, int y);
	static Vec2f GetCellCenter(int cellId);
	static AABB2f GetCellAABB(int x, int y);
	static AABB2f GetCellAABB(int x, int y, float expandRange);

	static void SetCollisionId(int cellId, int collisionId);
	static int GetCollisionIdFromPos(const Vec2f& pos);
	static int GetCollisionIdFromXY(int x, int y);
	static int GetCollisionIdFromCell(int idx);

	static float SphereRayIntersectCollision(const Ray2f& ray, float radius);
	static int RayIntersectCollisionId(const Ray2f& ray, Vec2f& intersectPos);
	static int RayIntersect(const Ray2f& ray, Vec2f& intersectPos);

	static int SelectEntitiesInRangeFast(Entity** entities, int maxEntities, Vec2f pos, float range, int flags);
	static int SelectEntitiesInRange(Entity** entities, int maxEntities, Vec2f pos, float range, int flags);
};

} // namespace Tmpl